<script setup lang="ts">
import {computed, watch} from 'vue'

const props = defineProps({
  // 控制抽屉显示隐藏
  visible: {
    type: Boolean,
    default: false
  },
  // 抽屉位置：left, right, top, bottom
  placement: {
    type: String,
    default: 'right',
    validator: (value: string) => ['left', 'right', 'top', 'bottom'].includes(value)
  },
  // 抽屉标题
  title: {
    type: String,
    default: ''
  },
  // 抽屉宽度或高度
  size: {
    type: [String, Number],
    default: 300
  },
  // 是否显示关闭按钮
  closable: {
    type: Boolean,
    default: true
  },
  // 是否显示头部
  showHeader: {
    type: Boolean,
    default: true
  },
  // 点击遮罩是否关闭
  maskClosable: {
    type: Boolean,
    default: true
  },
  // 层级
  zIndex: {
    type: Number,
    default: 1000
  }
})

const emit = defineEmits(['update:visible', 'confirm', 'close'])

// 抽屉样式类
const drawerClasses = computed(() => [
  'drawer',
  `drawer-${props.placement}`
])

// 抽屉样式
const drawerStyle = computed(() => {
  const isHorizontal = ['left', 'right'].includes(props.placement)
  const size = typeof props.size === 'number' ? `${props.size}px` : props.size

  return {
    zIndex: props.zIndex + 1,
    [isHorizontal ? 'width' : 'height']: size
  }
})

// 处理确认
const confirm = () => {
  emit('confirm')
}

// 处理关闭
const handleClose = () => {
  emit('update:visible', false)
  emit('close')
}

// 处理遮罩点击
const handleMaskClick = () => {
  if (props.maskClosable) {
    handleClose()
  }
}

// 监听ESC键
watch(() => props.visible, (newVal) => {
  if (newVal) {
    document.body.style.overflow = 'hidden'
    document.addEventListener('keydown', handleEscKey)
  } else {
    document.body.style.overflow = ''
    document.removeEventListener('keydown', handleEscKey)
  }
})

const handleEscKey = (e: KeyboardEvent) => {
  if (e.key === 'Escape') {
    handleClose()
  }
}
</script>

<template>
  <div>
    <!-- 遮罩层 -->
    <Transition name="mask">
      <div
          v-if="visible"
          class="drawer-mask"
          @click="handleMaskClick"
      ></div>
    </Transition>

    <!-- 抽屉容器 -->
    <Transition :name="`drawer-${placement}`">
      <div
          v-if="visible"
          :class="drawerClasses"
          :style="drawerStyle"
      >
        <!-- 抽屉头部 -->
        <div v-if="showHeader" class="drawer-header">
          <div class="drawer-title">{{ title }}</div>
          <button
              v-if="closable"
              class="drawer-close"
              @click="handleClose"
          >
            ×
          </button>
        </div>

        <!-- 抽屉内容 -->
        <div class="drawer-body">
          <slot></slot>
        </div>

        <!-- 抽屉底部 -->
        <div class="drawer-footer">
          <t-btn type="primary" @click="confirm">确 定</t-btn>
          <t-btn ghost @click="handleClose">取 消</t-btn>
        </div>
      </div>
    </Transition>
  </div>
</template>

<style scoped>
/* 遮罩层 */
.drawer-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.45);
  z-index: v-bind('props.zIndex');
}

/* 抽屉主体 */
.drawer {
  position: fixed;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
}

/* 不同方向的抽屉位置 */
.drawer-left {
  top: 0;
  left: 0;
  height: 100%;
}

.drawer-right {
  top: 0;
  right: 0;
  height: 100%;
}

.drawer-top {
  top: 0;
  left: 0;
  width: 100%;
}

.drawer-bottom {
  bottom: 0;
  left: 0;
  width: 100%;
}

/* 抽屉头部 */
.drawer-header {
  padding: 16px 24px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

.drawer-title {
  font-size: 16px;
  font-weight: 500;
  color: #262626;
}

.drawer-close {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #8c8c8c;
  padding: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s;
}

.drawer-close:hover {
  color: #262626;
}

/* 抽屉内容 */
.drawer-body {
  padding: 24px;
  flex: 1;
  overflow-y: auto;
}

/* 抽屉底部 */
.drawer-footer {
  padding: 16px 24px;
  border-top: 1px solid #f0f0f0;
  flex-shrink: 0;
  display: flex;
  justify-content: right;
}

/* 遮罩动画 */
.mask-enter-active,
.mask-leave-active {
  transition: opacity 0.3s ease;
}

.mask-enter-from,
.mask-leave-to {
  opacity: 0;
}

/* 左侧抽屉动画 */
.drawer-left-enter-active,
.drawer-left-leave-active {
  transition: transform 0.3s ease;
}

.drawer-left-enter-from,
.drawer-left-leave-to {
  transform: translateX(-100%);
}

/* 右侧抽屉动画 */
.drawer-right-enter-active,
.drawer-right-leave-active {
  transition: transform 0.3s ease;
}

.drawer-right-enter-from,
.drawer-right-leave-to {
  transform: translateX(100%);
}

/* 顶部抽屉动画 */
.drawer-top-enter-active,
.drawer-top-leave-active {
  transition: transform 0.3s ease;
}

.drawer-top-enter-from,
.drawer-top-leave-to {
  transform: translateY(-100%);
}

/* 底部抽屉动画 */
.drawer-bottom-enter-active,
.drawer-bottom-leave-active {
  transition: transform 0.3s ease;
}

.drawer-bottom-enter-from,
.drawer-bottom-leave-to {
  transform: translateY(100%);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .drawer-left,
  .drawer-right {
    width: 90% !important;
  }

  .drawer-top,
  .drawer-bottom {
    height: 80% !important;
  }

  .drawer-body {
    padding: 16px;
  }

  .drawer-header {
    padding: 12px 16px;
  }

  .drawer-footer {
    padding: 12px 16px;
  }
}
</style>